#include "matrixled.h"
// 串行输入口,每次只把1bit数据（最低位）送入移位寄存器
sbit SER = P3^4;
// 存储寄存器输入时钟
sbit RCLK = P3^5;
// 串行寄存器输入时钟，上升沿，数据就会写入串行寄存器
sbit SRCLK = P3^6;
// 点阵列控制端口
#define LEDDZ_COL_PORT P0

// 参考https://blog.csdn.net/m0_56399733/article/details/134075631

// 从第1行开始往下逐行亮起
unsigned char rowdata[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

// 心形图
unsigned char heartdata[8] = {0x38, 0x7C, 0x7E, 0x3F, 0x7E, 0x7C, 0x38, 0x00};

//I LOVE U 动画
/*--  宽度x高度=24x8  --*/
unsigned char ilu[40]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x41,0x7F,0x41,0x00,0x7F,0x01,0x00,
0x3F,0x21,0x3F,0x00,0x3E,0x01,0x3E,0x00,
0x3F,0x25,0x25,0x00,0x00,0x3F,0x01,0x3F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}


/*******************************************************************************
 * 函数功能      : 写入时钟置0
 * 输    出    	 : 无
 *******************************************************************************/
void clkinit()
{
    SRCLK = 0;
    RCLK = 0;
}

/*******************************************************************************
 * 函数功能      : 写入移位寄存器数据，对应LED的共阳极（行）
 * 输    入      : 阳极控制数据bit
 * 输    出    	 : 无
 *******************************************************************************/
void write_positice_data(unsigned char posidata)
{
    // 循环8次就将一个字节的数据写入到移位寄存器中
    for (i = 0; i < 8; i++)
    {
        // 595优先传输数据的高位(第一个从SER送入的bit将会从Q7出去,Q7对应高位)，所以有两种写法
        // 写法1,sbit接收二进制数据
        // SER =rowitem&(0x80>>i);
        // 写法2,发送最高位数据
        SER = posidata >> 7;
        // 左移一位，后面会发送次高位
        posidata <<= 1;
        // 上升沿数据写入移位寄存器
        SRCLK = 1;
        SRCLK = 0;
    }
    // 上升沿数据写入存储寄存器
    RCLK = 1;
    RCLK = 0;
}

/*******************************************************************************
 * 函数功能      : 逐行点亮led
 * 输    入      : 阳极控制数据bit
 * 输    出    	 : 无
 *******************************************************************************/
void write_rowbyrow()
{
    clkinit();
    LEDDZ_COL_PORT = 0x00;
    for (i = 0; i < 8; i++)
    {
        write_positice_data(0x00);
        write_positice_data(rowdata[i]);
    }
}

/*******************************************************************************
 * 函数功能      : 写入心型图，对应LED的共阴极（行）
 * 输    入      : 阴极控制数据bit
 * 输    出    	 : 无
 *******************************************************************************/
void write_heart_data(unsigned char nagidata)
{
    while (1)
    {
        // 循环8次,依次导通阴极列
        for (i = 0; i < 8; i++)
        {
            // 阴极导通
            LEDDZ_COL_PORT = ~(0x80 >> i);
            // 阳极就位
            write_positice_data(heartdata[i]);
        }
    }
}

void write_ilu(){
    //定义延时值,起始帧数
    unsigned int delaycount, frame_start_index=0;
    clkinit();
    while (1)
    {
         //每循环一次，固定8宽度画面，画面停留一段时间
         for (size_t i = 0; i < 8; i++)
         {
            // 阴极导通
            LEDDZ_COL_PORT = ~(0x80 >> i);
            // 阳极就位
            write_positice_data(ilu[frame_start_index+i]);
            // 阴极全部关闭，消影
            LEDDZ_COL_PORT=0xFF;
        }
        // 每一帧画面停留40次
        delaycount++;
        if(delaycount>40){
            //到时间后,下一帧画面
            frame_start_index++;
            delaycount=0;
            if(frame_start_index>=33){
                 // 已经移动到最后一帧数据，起始帧数重置,32时还可以遍历最后一轮数组的数据，但是到了33就不行了
                 frame_start_index=0;
            }
        }
    }
    
}

